package com.alibaba.base.user.servier.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import com.alibaba.base.common.RedisKeys;
import com.alibaba.base.user.mapper.UserMapper;
import com.alibaba.base.user.model.User;
import com.alibaba.base.user.model.UserExample;
import com.alibaba.base.user.servier.UserService;
import com.alibaba.base.util.BeanUtil;

/**
 * @author DP
 *
 */
@Service
@SuppressWarnings("unchecked")
public class UserServiceImpl implements UserService {
	
	@Autowired
	private UserMapper userMapper;
	@Autowired
	private RedisTemplate redisTemplate;
	
	
	/**
	 *新增用户
	 *
	 */
	public Long addUser(final User user) {
		
		final Long id=getId();
		user.setId(id);
		
		//final String key="model:"+User.class.getName()+":"+id;
		//final byte[] keys=redisTemplate.getStringSerializer().serialize(key);
		//final String zkye="all"+User.class.getName();
		final String key=String.format(RedisKeys.Model_KEY, User.class.getName(),id);
		final byte[] keys=redisTemplate.getStringSerializer().serialize(key);
		final String zkey=String.format(RedisKeys.MODEL_ALL,User.class.getName());
		
			redisTemplate.execute(new RedisCallback<User>() {
					//model:com.alibaba.base.user.service.impl.User:1
				public User doInRedis(RedisConnection connection) throws DataAccessException {
					connection.set(keys, redisTemplate.getValueSerializer().serialize(user));
					//zsort集合
					connection.zAdd(redisTemplate.getStringSerializer().serialize(zkey),id,keys);
					
					return null;
				}
			});
		
		return (long) userMapper.insert(user);

	}

	/**
	 * 修改用户
	 * @author DP
	 *@version 1.0
	 */
	public Long updateUser(final User user) {
		//final String key="model:"+User.class.getName()+":"+user.getId();
		//final byte[] keys=redisTemplate.getStringSerializer().serialize(key);
		final String key=String.format(RedisKeys.Model_KEY,User.class.getName(),user.getId());
		final byte[] keys=redisTemplate.getStringSerializer().serialize(key);
		
		final User userDB = getUserById(user.getId());
		BeanUtil.copyProperty(user, userDB);
		
		redisTemplate.execute(new RedisCallback<User>() {

			@Override
			public User doInRedis(RedisConnection connection) throws DataAccessException {
				connection.set(keys, redisTemplate.getValueSerializer().serialize(userDB));
				return null;
			}
		});
		//return (long) userMapper.updateByPrimaryKey(user);
				return (long) userMapper.updateByPrimaryKeySelective(user);//传什么改什么

	}

	/**
	 * 查询所有用户
	 * @author DP
	 *@version 1.0
	 */
	public List<User> gettUser() {
		final List<User> userList=new ArrayList<User>();
		final String zkye="all"+User.class.getName();
		redisTemplate.execute(new RedisCallback<User>() {
			@Override
			public User doInRedis(RedisConnection connection) throws DataAccessException {
				Set<byte[]> zRange = connection.zRange(redisTemplate.getStringSerializer().serialize(zkye), 0, -1);
				for (byte[] b : zRange) {
					userList.add((User) redisTemplate.getValueSerializer().deserialize(connection.get(b)));
					
				}
				return null;
			}
		});
		if(userList!=null&&userList.size()>0)
			return userList;
		
		return userMapper.selectByExample(new UserExample());
	}

	/**
	 * 根据id查询用户
	 * @author DP
	 *@version 1.0 
	 */
	public User getUserById(final Long id) {
		//final String key="model:"+User.class.getName()+":"+id;
		final String key=String.format(RedisKeys.Model_KEY, User.class.getName(),id);
		return (User) redisTemplate.execute(new RedisCallback<User>() {
			@Override
			public User doInRedis(RedisConnection connection) throws DataAccessException {
				byte[] userBytes = connection.get(redisTemplate.getStringSerializer().serialize(key));
				//反序列化
				User user= (User) redisTemplate.getValueSerializer().deserialize(userBytes);
				if(user==null) {
					//如果user为空则从数据中查，不为空直接返回user
					return userMapper.selectByPrimaryKey(id);
				}
				return user;
			}
		});
		
	}

	/**
	 * 根据id删除用户
	 * @author DP
	 *@version 1.0
	 */
	public Long deleteUser(Long id) {
		final String key="model:"+User.class.getName()+":"+id;
		
		final byte[] keys=redisTemplate.getStringSerializer().serialize(key);
		final String zkye="all"+User.class.getName();
		redisTemplate.execute(new RedisCallback<User>() {

			@Override
			public User doInRedis(RedisConnection connection) throws DataAccessException {
				connection.del(keys);
				connection.zRem(redisTemplate.getStringSerializer().serialize(zkye), keys);
				return null;
			}
		});
		
		
		return (long) userMapper.deleteByPrimaryKey(id);

	}
	
	//redis添加主键自增
	private Long getId() {
		final String key="model_id"+User.class.getName();
		 return (Long) redisTemplate.execute(new RedisCallback<Long>() {
			public Long doInRedis(RedisConnection connection) throws DataAccessException {
				return connection.incr(redisTemplate.getStringSerializer().serialize(key));
				
			}
		});
	}

}
